package com.ruoyi.activiti.service.cmd;

import com.ruoyi.common.core.utils.SpringUtils;
import lombok.Data;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.ActivitiEngineAgenda;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;

/**
 * 移动节点命令
 */
@Data
public class MoveSingleCommand implements Command<Object> {

    private String currentTaskId;
    private String targetNodeId;
    private RepositoryService repositoryService = SpringUtils.getBean(RepositoryService.class);

    public MoveSingleCommand(String currentTaskId, String targetNodeId) {
        this.currentTaskId = currentTaskId;
        this.targetNodeId = targetNodeId;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        TaskEntity taskEntity = taskEntityManager.findById(this.currentTaskId);
        ExecutionEntity executionEntity = executionEntityManager.findById(taskEntity.getExecutionId());
        Process process = repositoryService.getBpmnModel(taskEntity.getProcessDefinitionId()).getMainProcess();

        /**
         * 这种跳转方式会正确地更新task的endTime，但act_his_actinst不会受到影响
         */
        taskEntityManager.deleteTask(taskEntity, "节点跳转", false, false);//不完全删除

        FlowNode targetFlowElement = (FlowNode)process.getFlowElement(targetNodeId);//获取目标节点
        executionEntity.setCurrentFlowElement(targetFlowElement);

        ActivitiEngineAgenda agenda = commandContext.getAgenda();
        agenda.planContinueProcessInCompensation(executionEntity);
        return null;
    }
}
